local atan = math.atan
local sin = math.sin
local cos = math.cos
local rad = math.rad
local deg = math.deg
local bullet = require("bullet")
require("fishenum")

local launcher = {}

--[[
	config = {
		-- Id = 0,	-- 编号，创建实体时生成随机不重复的值
		Type = 0,	-- 类型，通过配置可以取名字，描述等信息
		PosX = 0,	-- 底边中点位置X
		PosY = 0,	-- 底边中点位置Y
		Angle = 0,	-- 转动角度
		Stat = 0,	-- 状态
		Level = 0,	-- 等级
		Point = 0,	-- 价值分数
		CD = 0,		-- 射击冷却时间
		HuntWeight = 0,	-- 捕获权重
		CDing = nil,-- 是否在冷却中
		Target = 0,	-- 追踪目标
	} 
--]]
local function init(entity, dinit)
	entity.Id 		= dinit.Id
	entity.Type 	= dinit.Type
	entity.PosX 	= dinit.PosX
	entity.PosY 	= dinit.PosY
	entity.Angle 	= dinit.Angle
	entity.Stat 	= dinit.Stat or EEntityStat.ALIVE
	entity.Level 	= dinit.Level or 1
	entity.Height	= dinit.Height
	entity.Width	= dinit.Width
	entity.Point	= dinit.Point
	entity.CD 		= dinit.CD or 20
	entity.HuntWeight	= dinit.HuntWeight
	entity.HitEntity	= nil
	entity.Rid			= dinit.Rid
	entity.SeatIndex	= dinit.SeatIndex
end

function launcher:new(s2csync, s2csyncex, dinit, obj)
	local entity = obj or {}
	init(entity, dinit)
	entity.s2csync = s2csync
	entity.s2csyncex = s2csyncex
	
	setmetatable(entity, self)
	self.__index = self
	-- entity:sync()	-- 时序问题，这里不需要立即同步
	return entity
end

function launcher:die()
	self.Speed = 0
	self.Stat = EEntityStat.DEAD
	self:sync()
end

function launcher:upgrade(data)
	init(self, data)
	self:sync()
end

function launcher:update_hitentity(entity)
	self.HitEntity = entity.Id
end

function launcher:turn(angle)
-- function launcher:turn(point)
	--[[
	local k = 0	-- 斜率，这里保证为正值
	local offset = 0
	if point[2] == self.PosY then		-- 水平移动
		if point[1] == self.PosX then	-- 如果出现这种情况会导致物体停在原地
			k = 0
			offset = 0
		elseif point[1] > self.PosX then
			k = 0
			offset = 90
		elseif point[1] < self.PosX then
			k = 0
			offset = 270
		end
	elseif point[2] > self.PosY then
		if point[1] == self.PosX then	-- 向上移动
			k = 0
			offset = 0
		elseif point[1] > self.PosX then
			k = (point[1] - self.PosX)/(point[2] - self.PosY)	-- 第一象限
			offset = 0
		elseif point[1] < self.PosX then
			k = (point[2] - self.PosY)/(self.PosX - point[1])	-- 第四象限
			offset = 270
		end
	else
		if point[1] == self.PosX then	-- 向下移动
			k = 0
			offset = 180
		elseif point[1] > self.PosX then
			k = (self.PosY - point[2])/(point[1] - self.PosX)	-- 第二象限
			offset = 90
		else
			k = (self.PosX - point[1])/(self.PosY - point[2])	-- 第三象限
			offset = 180
		end
	end
	self.Angle = deg(atan(k)) + offset
	-- self:sync()
	--]]
	self.Angle = angle
	self:sync_ex()
	-- print("launcher turn to:", self.Angle)
end

-- 射击有冷却时间
function launcher:checkcan_shoot(ts)
	return (self.CDing or 0) <= (ts or 0)
end

function launcher:shoot(sync, s2csyncex, config, ts)
	if self.Stat == EEntityStat.DEAD then return end
	config.Angle = self.Angle
	--[[ no use
	local len_x, len_y = 0, 0
	if self.Angle >= 0 and self.Angle < 90 then
		len_x = self.Height*sin(rad(self.Angle))
		len_y = self.Height*cos(rad(self.Angle))
	elseif self.Angle >= 90 and self.Angle < 180 then
		len_x = self.Height*cos(rad(self.Angle))
		len_y = self.Height*sin(rad(self.Angle))
	elseif self.Angle >= 180 and self.Angle < 270 then
		len_x = self.Height*sin(rad(self.Angle))
		len_y = self.Height*cos(rad(self.Angle))
	elseif self.Angle >= 270 and self.Angle <= 360 then
		len_x = self.Height*cos(rad(self.Angle))
		len_y = self.Height*sin(rad(self.Angle))
	end
	config.PosX = self.PosX + len_x
	config.PosY = self.PosY + len_y
	--]]
	local b = bullet:new(sync, s2csyncex, config, self)
	self.CDing = (ts or 0) + (self.CD - 5) / 100
	return b
end

function launcher:set_target(target)
	local oldtarget = self.Target
	self.Target = target
	if target ~= oldtarget then
		self:sync()
	end
end

function launcher:sync()
	if self.s2csync then
		self:s2csync()
	end
end

function launcher:sync_ex()
	if self.s2csyncex then
		self:s2csyncex()
	end
end

return launcher
